JS13K 게임 포트리스 게임: 오일러 적분

2026-07-27 · 2 min read

배경

포트리스풍 게임을 만들고 있다. 각도와 파워를 정해 포탄을 쏘는 게임이다.

포물선 운동이라 물리 엔진이 필요할 줄 알았는데, 찾아보니 중력 구현은 라이브러리 없이 세 줄이면 된다. 이 글에서는 그 세 줄이 어떻게 포물선을 만드는지 다룬다.

중력은 위치가 아니라 속도를 바꾼다

매 프레임 실행되는 코드는 이게 전부다.

vy += GRAVITY; // 속도에 중력을 더하고
x += vx; // 수평은 그대로 가고
y += vy; // 속도만큼 위치를 옮긴다

중력은 위치를 직접 바꾸는 힘이 아니라 속도를 바꾸는 힘이다. 가속도가 속도를 바꾸고, 속도가 위치를 바꾼다.

이게 포물선이 되는 이유는 단순하다. 수평 속도 vx는 아무도 건드리지 않으니 일정하고, 수직 속도 vy만 프레임마다 커진다. 가로 간격은 일정한데 세로 낙차가 점점 커지니 포물선이 그려진다. 포물선 공식은 코드 어디에도 없지만 결과는 포물선이다.

이 방식을 오일러 적분(Euler integration)이라고 부른다. 미분방정식 dv/dt = a, dy/dt = v를 잘게 쪼갠 시간 단위로 근사하는 수치 적분 기법인데, 이름이 거창할 뿐 실체는 위의 세 줄이다.

발사: 각도와 파워를 속도로 바꾼다

발사는 유저가 정한 각도와 파워를 초기 속도로 변환하면 된다.

const rad = (angle * Math.PI) / 180;
let vx = Math.cos(rad) * power;
let vy = -Math.sin(rad) * power;

vy에 마이너스가 붙는 이유는 캔버스 좌표계 때문이다. 캔버스는 y축이 수학과 반대로 아래 방향으로 커진다. 그래서 위로 쏘는 vy는 음수, 아래로 당기는 중력은 양수다. 처음 구현할 때 포탄이 땅으로 발사된다면 대부분 이 부호 문제다.

정리

  1. 중력은 속도에 매 프레임 더하는 작은 수 하나다. 가속도가 속도를 바꾸고, 속도가 위치를 바꾼다.
  2. 수평은 등속, 수직만 가속되므로 포물선이 저절로 그려진다. 이것이 오일러 적분이다.
  3. 캔버스는 y축이 아래로 커진다. 위로 쏘는 vy는 음수, 중력은 양수다.

다만 이 코드는 그대로 쓰면 모니터 주사율에 따라 포탄 속도가 달라진다. 이 문제는 다음 글에서 deltaTime으로 해결한다.